package org.jetlinks.community.mstn.service;

import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.crud.service.GenericReactiveCrudService;
import org.hswebframework.web.exception.BusinessException;
import org.jetlinks.community.device.entity.DeviceInstanceEntity;
import org.jetlinks.community.device.enums.DeviceType;
import org.jetlinks.community.device.service.LocalDeviceInstanceService;
import org.jetlinks.community.device.service.LocalDeviceProductService;
import org.jetlinks.community.mstn.entity.DeviceAliasEntity;
import org.jetlinks.community.mstn.entity.vo.DeviceAliasListResVO;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

@Service
@AllArgsConstructor
public class DeviceAliasService extends GenericReactiveCrudService<DeviceAliasEntity, String> {

    private final LocalDeviceInstanceService deviceInstanceService;

    private final LocalDeviceProductService productService;
    /**
     * 通过categoryId 修改categoryName
     * @param categoryId
     * @param categoryName
     * @return
     */
    public Mono<Integer> updateCategoryName(String categoryId, String categoryName){
        return createUpdate().where(DeviceAliasEntity::getCategoryId,categoryId)
               .set(DeviceAliasEntity::getCategoryName,categoryName)
               .execute();
    }

    /**
     * 通过siteId 修改siteName
     * @param siteId
     * @param siteName
     * @return
     */
    public Mono<Integer> updateSiteName(String siteId, String siteName){
        return createUpdate().where(DeviceAliasEntity::getSiteId,siteId)
            .set(DeviceAliasEntity::getSiteName,siteName)
            .execute();
    }

    /**
     * 通过groupId 修改groupName
     * @param groupId
     * @param groupName
     * @return
     */
    public Mono<Integer> updateGroupName(String groupId, String groupName){
        return createUpdate().where(DeviceAliasEntity::getGroupId,groupId)
            .set(DeviceAliasEntity::getGroupName,groupName)
            .execute();
    }



    /**
     * 校验分类下是否有数字孪生
     * @param categoryId
     * @return
     */
    public Mono<Void> assertNotReferenced(String categoryId) {
        return createQuery().where(DeviceAliasEntity::getCategoryId,categoryId)
                .fetch().collectList()
                .filter(CollectionUtils::isNotEmpty)
                .flatMap(list -> Mono.error(new BusinessException("分类下存在数字孪生")));
    }

    /**
     * 校验站点下是否有数字孪生
     * @param siteId
     * @return
     */
    public Mono<Void> siteNotReferenced(String siteId) {
        return createQuery().where(DeviceAliasEntity::getSiteId,siteId)
            .fetch().collectList()
            .filter(CollectionUtils::isNotEmpty)
            .flatMap(list -> Mono.error(new BusinessException("站点下存在数字孪生")));
    }


    /**
     * 校验分组下是否有数字孪生
     * @param groupId
     * @return
     */
    public Mono<Void> groupNotReferenced(String groupId) {
        return createQuery().where(DeviceAliasEntity::getGroupId,groupId)
            .fetch().collectList()
            .filter(CollectionUtils::isNotEmpty)
            .flatMap(list -> Mono.error(new BusinessException("分组下存在数字孪生")));
    }

    public Mono<PagerResult<DeviceAliasEntity>> queryDeviceAlias(QueryParamEntity query){
        return queryPager(query);
    }


    /**
     * 查询所有网关
     * @param query
     * @return
     */
    public Mono<PagerResult<DeviceInstanceEntity>> getGatewayProductList(QueryParamEntity query) {
        Term term = new Term();
        term.setColumn("deviceType");
        term.setTermType("eq");
        term.setValue(DeviceType.gateway);
        query.getTerms().add(term);
        return deviceInstanceService.queryPager(query);
    }

    /**
     * 查询所有终端
     * @param query
     * @return
     */
    public Mono<PagerResult<DeviceInstanceEntity>> getDeviceList(QueryParamEntity query) {
        Term term = new Term();
        term.setColumn("deviceType");
        term.setTermType("not");
        term.setValue(DeviceType.gateway);
        query.getTerms().add(term);
        return deviceInstanceService.queryPager(query);
    }
}
